<!--

高德定位组件

-->

<template>
  <div :class="['if-amap', showCtrl ? '': 'hide']" :style="container.style">
    <div :id="container.id" :style="container.style"></div>
    <div class="disabled-layer" v-if="disabled"></div>
    <input
      :disabled="disabled"
      :id="searchInput.id"
      :style="searchInput.style"
      :placeholder="searchInput.placeholder"
    />
  </div>
</template>

<script lang="ts">
import {
  defineComponent,
} from 'vue'
import _ from 'lodash'
import config from './config'
import {
  getConfig,
  aMapLoaderHandler,
  mapContainerInit,
  scaleSettingHandler,
  toolBarSettingHandler,
  geoLocationHandler,
  designativeLocationHandler,
  poiSearchHandler,
  mapClickListener
} from './tool'

export default defineComponent({
  name: 'AMap',
  props: {
    // 定位成功的回调
    geoSuccessFn: {
      type: Function,
      default: () => () => {}
    },
    // 定位失败的回调
    geoFailFn: {
      type: Function,
      default: () => () => {}
    },
    // poi搜索的回调
    poiSelectFn: {
      type: Function,
      default: () => () => {}
    },
    // 基于经纬度查询名称的回调配置
    geoCoderCompleteFn: {
      type: Function,
      default: () => () => {}
    },
    // 容器信息
    containerInfo: {
      type: Object,
      default: () => {}
    },
    // 搜索框input信息
    searchInputInfo: {
      type: Object,
      default: () => {}
    },
    // 回显时的定位
    locationInfo: {
      type: Object,
      default: () => {}
    },
    // 地图类型：定位
    shouldLocation: {
      type: Boolean,
      default: false
    },
    // 控制显示
    showCtrl: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    container() {
      const result:any = { ...config.containerInfoDefault, ...this.containerInfo }
      return _.cloneDeep(result)
    },
    searchInput() {
      const result:any = { ...config.searchInputDefault, ...this.searchInputInfo }
      return _.cloneDeep(result)
    }
  },
  data() {
    return {
      map: null,
      AMap: null
    }
  },
  methods: {
    // 模拟接口获取加密后的key配置信息
    async initMap() {
      // 1. 获取配置文件
      const conf = await getConfig()
      // 2. 初始化加载器 获取AMap实例
      const AMapResult:any = await aMapLoaderHandler(conf)
      const AMap:any = AMapResult.data
      if (!AMapResult.success) {
        console.log(AMap)
        return
      }
      // 3. 地图容器初始化
      const map = mapContainerInit(AMap, this.container.id)
      // 4. 配置比例尺缩放
      scaleSettingHandler(map, AMap)
      // 5. 配置工具条
      toolBarSettingHandler(map, AMap)
      // 6. 配置POI搜索
      poiSearchHandler(map, AMap, this.searchInput.id, this.poiSelectFn)
      // 7. 配置地图点击监听
      mapClickListener(map, AMap, this.geoCoderCompleteFn)
      // 8. 挂载当前地图实例对象
      this.map = map
      this.AMap = AMap
      // 9. 更新地图 (定位、回显)
      this.updateMap()
    },
    // 更新地图
    updateMap() {
      const { shouldLocation, locationInfo } = this
      // 1. 配置定位 没有经纬度，进行正常定位
      if (shouldLocation && !locationInfo?.lat) {
        this.doGeoLocation()
      } else if (locationInfo?.lat) {
        // 2. 配置回显 有经纬度，定位到当前经纬度的位置
        this.doDesignativeLocation()
      }
    },
    // 定位功能
    doGeoLocation() {
      const { map, AMap, geoSuccessFn, geoCoderCompleteFn } = this
      geoLocationHandler(map, AMap, geoSuccessFn, geoCoderCompleteFn)
    },
    // 回显功能
    doDesignativeLocation() {
      const { map, AMap, locationInfo } = this
      designativeLocationHandler(map, AMap, locationInfo)
    }
  },
  created() {
    // DOM初始化完成进行地图初始化
    this.initMap()
  }
})

</script>

<style lang="less" scoped>
  .if-amap.hide {
    z-index: -1!important;
  }
  .disabled-layer {
    width: 100%;
    top: 0;
    bottom: 0;
    position: absolute;
    z-index: 999;
    background: transparent;
  }
  :deep(.amap-copyright) {
    bottom: 10px;
  }
</style>
